package com.ctshk.rpc.goods.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ctshk.common.dto.Result;
import com.ctshk.common.enums.GlobalConstants;
import com.ctshk.common.enums.IsDeletedCode;
import com.ctshk.common.enums.SystemError;
import com.ctshk.common.exception.BusinessException;
import com.ctshk.common.model.PageResponse;
import com.ctshk.common.model.TokenUser;
import com.ctshk.common.utils.EntityUtil;
import com.ctshk.rpc.goods.dto.ShoppingSpecialCommodityDTO;
import com.ctshk.rpc.goods.dto.ShoppingSpecialCommodityDetailedDTO;
import com.ctshk.rpc.goods.dto.ShoppingSpecialDetailedDTO;
import com.ctshk.rpc.goods.dto.ShoppingSpecialPageDTO;
import com.ctshk.rpc.goods.entity.ShoppingSpecial;
import com.ctshk.rpc.goods.entity.ShoppingSpecialCommodity;
import com.ctshk.rpc.goods.mapper.CommodityMapper;
import com.ctshk.rpc.goods.mapper.ShoppingSpecialCommodityMapper;
import com.ctshk.rpc.goods.mapper.ShoppingSpecialMapper;
import com.ctshk.rpc.goods.req.ShoppingSpecialCommodityReq;
import com.ctshk.rpc.goods.req.ShoppingSpecialPageReq;
import com.ctshk.rpc.goods.req.ShoppingSpecialReq;
import com.ctshk.rpc.goods.service.IShoppingSpecialService;
import com.ctshk.rpc.system.service.ISysPermissionService;
import org.apache.dubbo.common.utils.CollectionUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 * 商城专题 服务实现类
 * </p>
 *
 * @author 姜斌文
 * @since 2021-04-30
 */
@DubboService
public class ShoppingSpecialServiceImpl extends ServiceImpl<ShoppingSpecialMapper, ShoppingSpecial> implements IShoppingSpecialService {

    @Autowired
    private ShoppingSpecialMapper shoppingSpecialMapper;

    @Autowired
    private ShoppingSpecialCommodityMapper shoppingSpecialCommodityMapper;

    @Autowired
    private CommodityMapper commodityMapper;

    @DubboReference
    private ISysPermissionService sysPermissionService;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void addShoppingSpecial(ShoppingSpecialReq addReq, TokenUser tokenUser) {
        if (addReq == null) {
            throw new BusinessException(SystemError.SYS_402);
        }
        if (tokenUser == null) {
            throw new BusinessException(SystemError.SYS_406);
        }
        LocalDateTime now = LocalDateTime.now();
        ShoppingSpecial shoppingSpecial = new ShoppingSpecial();
        BeanUtils.copyProperties(addReq, shoppingSpecial);
        shoppingSpecial.setCreateId(tokenUser.getId());
        shoppingSpecial.setGmtCreate(now);
        shoppingSpecial.setModifiedId(tokenUser.getId());
        shoppingSpecial.setGmtModified(now);
        shoppingSpecial.setIsDeleted(IsDeletedCode.NO.getCode());
        shoppingSpecial.setIsDisplay(addReq.getIsDisplay() == null ? 1 : 0); //如果為空，默認為顯示，0：不显示;1：显示
        shoppingSpecialMapper.insert(shoppingSpecial);

        List<ShoppingSpecialCommodityReq> shoppingSpecialCommodityList  = addReq.getShoppingSpecialCommodityReqList();
        if (null != shoppingSpecialCommodityList && shoppingSpecialCommodityList.size() > 20){
            throw new BusinessException(SystemError.MALL_MERCHANDISE_23031);
        }
        if (null != shoppingSpecialCommodityList && shoppingSpecialCommodityList.size() > 0){
            for (ShoppingSpecialCommodityReq commodityReq : shoppingSpecialCommodityList) {
                ShoppingSpecialCommodity shoppingSpecialCommodity = new ShoppingSpecialCommodity();
                BeanUtils.copyProperties(commodityReq, shoppingSpecialCommodity);
                shoppingSpecialCommodity.setSpecialId(shoppingSpecial.getId());
                shoppingSpecialCommodity.setCreateId(tokenUser.getId());
                shoppingSpecialCommodity.setGmtCreate(now);
                shoppingSpecialCommodity.setModifiedId(tokenUser.getId());
                shoppingSpecialCommodity.setGmtModified(now);
                shoppingSpecialCommodity.setIsDeleted(IsDeletedCode.NO.getCode());
                shoppingSpecialCommodityMapper.insert(shoppingSpecialCommodity);
            }
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateShoppingSpecial(ShoppingSpecialReq upReq, TokenUser tokenUser) {
        if (upReq == null || null == upReq.getId()) {
            throw new BusinessException(SystemError.SYS_402);
        }
        if (tokenUser == null) {
            throw new BusinessException(SystemError.SYS_406);
        }
        LocalDateTime now = LocalDateTime.now();
        ShoppingSpecial dbShoppingSpecial = shoppingSpecialMapper.selectById(upReq.getId());
        BeanUtils.copyProperties(upReq, dbShoppingSpecial);
        dbShoppingSpecial.setModifiedId(tokenUser.getId());
        dbShoppingSpecial.setGmtModified(now);
        shoppingSpecialMapper.updateById(dbShoppingSpecial);
        if (null != upReq.getOperationType() && upReq.getOperationType() == 2) {
            return; // 操作类型：为2时，表示更新显示状态，即可结束逻辑操作，不用执行后续代码逻辑
        }

        List<ShoppingSpecialCommodityReq> shoppingSpecialCommodityList =  upReq.getShoppingSpecialCommodityReqList();
        if (null != shoppingSpecialCommodityList && shoppingSpecialCommodityList.size() > 0) {
            List<ShoppingSpecialCommodity> upShoppingSpecialCommodity  = new ArrayList<>();
            List<ShoppingSpecialCommodity> addShoppingSpecialCommodity  = new ArrayList<>();
            List<ShoppingSpecialCommodity> dbShoppingSpecialCommodity = shoppingSpecialCommodityMapper.findShoppingSpecialCommodityBySpecialId(dbShoppingSpecial.getId());
            //Map<Long, List<ShoppingSpecialCommodity>> dbShoppingSpecialCommodityMap = dbShoppingSpecialCommodity.stream().collect(Collectors.groupingBy(obj -> obj.getId()));
            for (ShoppingSpecialCommodityReq current :shoppingSpecialCommodityList) {
                ShoppingSpecialCommodity shoppingSpecialCommodity = new ShoppingSpecialCommodity();
                if (current.getId() == null) {
                    BeanUtils.copyProperties(current, shoppingSpecialCommodity);
                    shoppingSpecialCommodity.setSpecialId(dbShoppingSpecial.getId());
                    shoppingSpecialCommodity.setCreateId(tokenUser.getId());
                    shoppingSpecialCommodity.setGmtCreate(now);
                    shoppingSpecialCommodity.setModifiedId(tokenUser.getId());
                    shoppingSpecialCommodity.setGmtModified(now);
                    shoppingSpecialCommodity.setIsDeleted(IsDeletedCode.NO.getCode());
                    addShoppingSpecialCommodity.add(shoppingSpecialCommodity);
                    continue;
                }
                for (ShoppingSpecialCommodity db :dbShoppingSpecialCommodity) {
                    if (current.getId().longValue() == db.getId().longValue()){
                        BeanUtils.copyProperties(current, db);
                        db.setModifiedId(tokenUser.getId());
                        db.setGmtModified(now);
                        upShoppingSpecialCommodity.add(db);
                        shoppingSpecialCommodityMapper.updateById(db);
                        dbShoppingSpecialCommodity.remove(db);
                        break;
                    }
                }
            }
            if (CollectionUtils.isNotEmpty(addShoppingSpecialCommodity)) {
                shoppingSpecialCommodityMapper.insertBatchSomeColumn(addShoppingSpecialCommodity);
            }
            if (CollectionUtils.isNotEmpty(dbShoppingSpecialCommodity)) {
                List<Long> ids = dbShoppingSpecialCommodity.stream().map(p ->p.getId()).collect(Collectors.toList());
                shoppingSpecialCommodityMapper.deleteBatchIds(ids);
            }
        }
    }

    @Override
    public PageResponse<ShoppingSpecialPageDTO> findShoppingSpecialPageList(ShoppingSpecialPageReq pageReq, TokenUser currentUser) {

        Result<List<Long>> permissionResult = sysPermissionService.queryPermission(pageReq.getMenuId(), currentUser.getId());
        if (!permissionResult.isSuccess()) {
            SystemError result = SystemError.getDefined(permissionResult.getCode());
            throw new BusinessException(result);
        }
        //不是管理员
        if (!GlobalConstants.Role.isAdmin(currentUser.getUsername())) {
            pageReq.setIsNotAdmin(1);
            String ids = "";
            List<Long> data = permissionResult.getData();
            if(data != null && data.size() >0){
                for (Long datum : data) {
                    ids += datum + ",";
                }
            }
            if(ids.length() > 0){
                ids = ids.substring(0, ids.length() - 1);
            }
            pageReq.setUserIds(ids);
        }

        // 当前登陆用户只能查看运营人员为自己的专题信息
        pageReq.setOperatorId(currentUser.getId());
        IPage<ShoppingSpecialPageDTO> page = new Page<ShoppingSpecialPageDTO>(pageReq.getPageNo(),pageReq.getPageSize());
        IPage<ShoppingSpecialPageDTO> iPage = shoppingSpecialMapper.findShoppingSpecialPageByCondition(page, pageReq);
        List<ShoppingSpecialPageDTO> recordsList = iPage.getRecords();
        List<ShoppingSpecialPageDTO> pageDTOList = EntityUtil.copyList(recordsList, ShoppingSpecialPageDTO.class);
        return new PageResponse<>(pageDTOList, iPage.getCurrent() == 1,
                iPage.getTotal() <= (iPage.getCurrent() * iPage.getSize()),
                iPage.getTotal(), iPage.getCurrent(), iPage.getSize());
    }

    @Override
    public ShoppingSpecialDetailedDTO findShoppingSpecialDetailed(ShoppingSpecialPageReq req, TokenUser currentUser) {
        if (req == null || null == req.getId()) {
            throw new BusinessException(SystemError.SYS_402);
        }
        if (currentUser == null) {
            throw new BusinessException(SystemError.SYS_406);
        }
        ShoppingSpecial dbShoppingSpecial = shoppingSpecialMapper.selectById(req.getId());
        if (dbShoppingSpecial == null) {
            throw new BusinessException(SystemError.MALL_MERCHANDISE_23032);
        }
        ShoppingSpecialDetailedDTO shoppingSpecialDetailedDTO = new ShoppingSpecialDetailedDTO();

        QueryWrapper<ShoppingSpecialCommodity> queryCommodity = new QueryWrapper<ShoppingSpecialCommodity>();
        queryCommodity.lambda().eq(ShoppingSpecialCommodity::getSpecialId,dbShoppingSpecial.getId());
        queryCommodity.lambda().eq(ShoppingSpecialCommodity::getIsDeleted,0);
        List<ShoppingSpecialCommodity> dbSpecialCommodityList = shoppingSpecialCommodityMapper.selectList(queryCommodity);
        List<ShoppingSpecialCommodityDetailedDTO> dbSpecialCommodityDetailedList = EntityUtil.copyList(dbSpecialCommodityList, ShoppingSpecialCommodityDetailedDTO.class);
        BeanUtils.copyProperties(dbShoppingSpecial, shoppingSpecialDetailedDTO);
        if (CollectionUtils.isNotEmpty(dbSpecialCommodityDetailedList)) {
            List<Long> ids = dbSpecialCommodityDetailedList.stream().map(obj ->obj.getCommodityId()).collect(Collectors.toList());
            ids = ids.stream().distinct().collect(Collectors.toList()); // 去重
            String commodityIds = ids.toString().substring(1, ids.toString().length()- 1);
            // 获取指定的商品信息
            List<ShoppingSpecialCommodityDTO>  shoppingSpecialCommodityDTO = commodityMapper.findShoppingSpecialCommodityByIds(commodityIds);
            // 对象集合转换成map
            Map<Long,ShoppingSpecialCommodityDTO> commodityMap = shoppingSpecialCommodityDTO.stream().
                    collect(Collectors.toMap(ShoppingSpecialCommodityDTO::getId, Function.identity(), (key1, key2) -> key1));
            // 商品图片、价格、名称等赋值到商品专题，用于前端页面展示
            for (ShoppingSpecialCommodityDetailedDTO target: dbSpecialCommodityDetailedList) {
                ShoppingSpecialCommodityDTO source = commodityMap.get(target.getCommodityId());
                if (null != source){
                    target.setCommodityName(source.getCommodityName());
                    target.setFileUrl(source.getFileUrl());
                    target.setPrice(source.getCostPrice());
                    target.setStock(source.getStock());
                }
            }
            shoppingSpecialDetailedDTO.setCommodityDetailedList(dbSpecialCommodityDetailedList);
        }
        return shoppingSpecialDetailedDTO;
    }
}
